home *** CD-ROM | disk | FTP | other *** search
- // ASIPChallenge.cp - base class for Appleshare IP Challenge Object
- //
- // Apple Macintosh Developer Technical Support
- // Written by: Vinnie Moscaritolo
- //
- // Copyright (work in progress) Apple Computer, Inc All rights reserved.
- //
- // You may incorporate this sample code into your applications without
- // restriction, though the sample code has been provided "AS IS" and the
- // responsibility for its operation is 100% yours. However, what you are
- // not permitted to do is to redistribute the source as "DSC Sample Code"
- // after having made changes. If you're going to re-distribute the source,
- // we require that you make it clear in the source that the code was
- // descended from Apple Sample Code, but that you've made changes.
- //
-
-
- #include <string.h>
- #include <TextUtils.h>
- #include <PLStringFuncs.h>
-
- #include "ASIPChallenge.h"
- #include "PassphraseCache.h"
- #include "TPGPException.h"
-
- #include "pgpRandomPool.h"
- #include "pgpUserInterface.h"
-
-
- // ---------------------------------------------------------------------------
- void MakeChallenge(TPGPkey *theKey, StringPtr outBuf)
- // ---------------------------------------------------------------------------
- //
- // outBuf --> [len][challenge]
- {
-
- PGPSize challengeSize;
- PGPError err;
-
- challengeSize = theKey->GetHashSize();
-
- while ((err = PGPContextGetRandomBytes(TPGPkey::fgContext, &outBuf[1], challengeSize)) == kPGPError_OutOfEntropy )
- {
- // handle entropy errors?
- // what about no UI?
- ThrowIfPGPErr(
- PGPCollectRandomDataDialog(TPGPkey::fgContext,
- PGPGlobalRandomPoolGetMinimumEntropy() - PGPGlobalRandomPoolGetEntropy(),
- PGPOLastOption(TPGPkey::fgContext )));
- }
- ThrowIfPGPErr(err);
-
- outBuf[0] = challengeSize & 0xFF;
-
- }
-
-
- #define counterChallengeSize 64
-
- // ---------------------------------------------------------------------------
- void ReplyToChallenge(TPGPkey *serverKey, const char *passPhrase, TPGPkey *clientKey, StringPtr inBuf, StringPtr outBuf)
- // ---------------------------------------------------------------------------
- //
- // inBuf --> [len][challenge]
- //
- // outBuf <-- [len of total][offset to orig challenge][counterchallenge] [sig]
-
- {
-
- UInt8 *counterChallenge = (UInt8*) outBuf + 1;
- UInt8 offset;
- PGPSize sigBufSize = 0;
-
- ThrowPGPErrIfTrue( clientKey->GetHashSize() * 2 > counterChallengeSize , kPGPError_BufferTooSmall);
-
- // calculate counter challenge string
- PGPContextGetRandomBytes(TPGPkey::fgContext, counterChallenge, counterChallengeSize );
-
- // offset the challenge into the counterchallenge
- offset = counterChallengeSize - inBuf[0] - (counterChallenge[0] & 0x1F);
- ThrowPGPErrIfTrue ( offset < 1, kPGPError_BufferTooSmall);
- counterChallenge[0] = offset;
- memcpy(&counterChallenge[offset], inBuf+1, inBuf[0]);
-
- // sign the counter challenge
- if(serverKey && serverKey->CanSign() )
- serverKey->Sign(counterChallenge, counterChallengeSize , counterChallenge + counterChallengeSize, &sigBufSize, passPhrase);
-
- outBuf[0] = (sigBufSize & 0xFF) + 64;
-
-
- }
-
-
- // ---------------------------------------------------------------------------
- Boolean VerifyChallenge(TPGPkey *theKey,StringPtr origChallenge, StringPtr inBuf)
- // ---------------------------------------------------------------------------
- //
- // origChallenge <-- [len][challenge]
- // inBuf <-- [len of total][offset to orig challenge][counterchallenge] [sig]
- //
- {
-
- // check if challenge string is correct.
- if(!(memcmp( &inBuf[ inBuf[1] + 1] , &origChallenge[1], origChallenge[0]) == 0 ))
- return false;
-
- // check sig
- return theKey->Verify( &inBuf[1], 64, &inBuf[65], inBuf[0] - 64);
-
- }
-
- // ---------------------------------------------------------------------------
- PGPError ReplyToCounterChallenge(StringPtr promptString, StringPtr fpBuf, StringPtr inBuf, StringPtr outBuf)
- // ---------------------------------------------------------------------------
- //
- // fpBuf <-- [len][fingerprint of challenged]
- // inBuf <-- [len of total][offset to orig challenge][counterchallenge] [sig]
- // outbuf --> [len of sig] [sig]
- //
- //
- {
- PGPFilterRef theFilter = kInvalidPGPFilterRef;
- PGPKeyIterRef theIterator = kInvalidPGPKeyIterRef;
- PGPKeyListRef theKeyListRef = kInvalidPGPKeyListRef;
- PGPKeyRef theKeyRef = kInvalidPGPKeyRef;
- PGPOptionListRef optionList = kInvalidPGPOptionListRef;
- PGPContextRef context = TPGPkey::fgContext;
- PGPKeySetRef newKeySet = NULL;
- PGPUInt32 numKeys;
- PGPError err = noErr;
-
- // Find key in database
- ThrowIfPGPErr( PGPNewKeyFingerPrintFilter(TPGPkey::fgContext,&fpBuf[1],fpBuf[0] , &theFilter));
- ThrowIfPGPErr( PGPFilterKeySet(TPGPkey::fgPGPKeySetRef , theFilter, &newKeySet));
- PGPFreeFilter(theFilter);
- ThrowIfPGPErr( PGPCountKeys(newKeySet, &numKeys));
-
- if(numKeys != 1)
- err = kPGPError_KeyInvalid;
- else
- {
- unsigned char promptStr[256];
- char *thePassphrase = NULL;
-
- ThrowIfPGPErr( PGPOrderKeySet(newKeySet,kPGPAnyOrdering, &theKeyListRef));
- ThrowIfPGPErr( PGPNewKeyIter( theKeyListRef, &theIterator ));
- ThrowIfPGPErr( PGPKeyIterNext( theIterator, &theKeyRef ));
-
- ThrowIfPGPErr ( PGPBuildOptionList( context, &optionList,
- PGPOUIOutputPassphrase(context, &thePassphrase),
- PGPOUIDefaultKey(context, theKeyRef),
- PGPOUIVerifyPassphrase(context, true),
- PGPOLastOption(context) ));
-
- if(promptString)
- {
- ThrowIfPGPErr ( PGPAppendOptionList( optionList,
- PGPOUIDialogPrompt(context, (char *)promptString),
- PGPOLastOption(context) ));
- };
-
- if( GetPassphrase(TPGPkey::fgContext, theKeyRef, &thePassphrase)
- || ( (err = PGPSigningPassphraseDialog(context, newKeySet, &theKeyRef,
- optionList,
- PGPOLastOption(TPGPkey::fgContext ))) == kPGPError_NoErr )
- && (RememberPassphrase(theKeyRef, thePassphrase), true))
- {
- TPGPkey theKey;
- PGPSize sigBufSize;
-
- theKey.Initialize(theKeyRef);
-
- if( theKey.IsOperational())
- {
- if( ! theKey.Sign(&inBuf[1], 64, &outBuf[1], &sigBufSize, thePassphrase))
- err = kPGPError_KeyInvalid;
- outBuf[0] = (sigBufSize & 0xFF);
- }
-
- // Erase passphrase
- PGPFreeData(thePassphrase);
- thePassphrase = NULL;
- }
-
- if(err == kPGPError_UserAbort) err = userCanceledErr;
-
- }
- PGPFreeOptionList(optionList);
- PGPFreeKeyIter(theIterator );
- PGPFreeKeyList(theKeyListRef );
- PGPFreeKeySet(newKeySet );
-
- return err;
- }
-
-
- // ---------------------------------------------------------------------------
- Boolean VerifyCounterChallenge(TPGPkey *theKey, StringPtr origCounterChallenge, StringPtr inBuf)
- // ---------------------------------------------------------------------------
- //
- // origCounterChallenge <-- [len of total][offset to orig challenge][counterchallenge] [sig]
- // inBuf <-- [len of sig] [sig]
-
- {
-
- return theKey->Verify( &origCounterChallenge[1], 64, &inBuf[1], inBuf[0]);
-
- }
-
-
-
-